package app

import (
	"context"
	_ "embed"
	"github.com/gorilla/websocket"
	"github.com/rs/cors"
	"go.uber.org/fx"
	"go.uber.org/zap"
	"html/template"
	"net/http"
)

//go:embed mainPage.tmpl
var templat string

var tmpl = template.Must(template.New("mainPage").Parse(templat))

type templateData struct {
	IsDevelopment    bool
	TotalConnections int
	Connections      []string
}

func newHttp() fx.Option {
	return fx.Module("Http", fx.Invoke(func(upgrader *websocket.Upgrader, cfg *Config, logger *zap.Logger, emitter *Emitter, lc fx.Lifecycle) {
		http.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {
			connections := []string{}
			for k := range emitter.connections {
				connections = append(connections, k)
			}
			writer.Header().Set("Content-Type", "text/html")
			tmpl.Execute(writer, templateData{
				IsDevelopment:    cfg.Environment == "development",
				TotalConnections: len(emitter.connections),
				Connections:      connections,
			})
		})

		http.HandleFunc("/websocket/", func(w http.ResponseWriter, r *http.Request) {
			c, err := upgrader.Upgrade(w, r, nil)
			if err != nil {
				logger.Error("failed to upgrade connection", zap.Error(err))
				return
			}
			emitter.track(c)
		})

		lc.Append(fx.Hook{
			OnStart: func(ctx context.Context) error {
				handler := cors.AllowAll().Handler(http.DefaultServeMux)
				go http.ListenAndServe(":"+cfg.AppPort, handler)
				return nil
			},
		})
	}))
}
